
import java.io.IOException;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class HeroGame extends GameCanvas implements Runnable, CommandListener {

    private TiledLayer mGround;
    private TiledLayer mStone;
    private Hero mHero;
    private LayerManager mLayerManager = new LayerManager();
    private float sx = 300;
    private Midlet midlet;
    private Form menu;
    public AudioService audio;
    private SubOpponent mEnemy;
    private boolean isEnemyAlive = true;
    float x1 = 10f;
    float x2 = 1f;
    int score =10000;

    HeroGame(Midlet midlet, Form menu) {

        super(true);
        this.menu = menu;
        this.midlet = midlet;
        createGame();
        new Thread(this).start();
        audio = new AudioService("Nhac_nen_hero.wav");
        audio.playFromResource();
    }

    private void createGround(Graphics g, Image im) {
        g = getGraphics();
        mGround = new TiledLayer(44, 10, im, 32, 32);

        int[] map = {
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};

        for (int i = 0; i < map.length; i++) {
            int column = i % 44;
            int row = (i - column) / 44;
            mGround.setCell(column, row, map[i]);
        }
        mLayerManager.append(mGround);
        mLayerManager.paint(g, 0, 0);
    }

    private void createStone(Graphics g, Image im) {
        mStone = new TiledLayer(44, 10, im, 32, 32);
        int[] map = {
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
        for (int i = 0; i < map.length; i++) {
            int column = i % 44;
            int row = (i - column) / 44;
            mStone.setCell(column, row, map[i]);
        }
        mLayerManager.append(mStone);
    }

    private void createHero(Graphics g) {
        try {
            Image im = Image.createImage("/Hero.png");
            mHero = new Hero(im, 23, 41);
            mHero.setFrame(mHero.framefomove);
            mHero.setPosition(50, 80);
            mHero.defineReferencePixel(12, 21);
            mLayerManager.append(mHero);

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    private TiledLayer mFire;

    private void createFire(Graphics g, Image im) {
        mFire = new TiledLayer(44, 10, im, 32, 32);
        int[] map = {
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 5, 5, 0, 5, 5, 0, 5, 5, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

        for (int i = 0; i < map.length; i++) {
            int column = i % 44;
            int row = (i - column) / 44;
            mFire.setCell(column, row, map[i]);
        }
        mLayerManager.append(mFire);
    }

    private void createGame() {
        try {
            Graphics g = getGraphics();
            Image im = Image.createImage("/tile.png");
            createHero(g);
            createEnemy(g);
            createFire(g, im);
            createStone(g, im);
            createGround(g, im);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void createEnemy(Graphics g) {
        try {
            Image im = Image.createImage("/enemy.png");
            mEnemy = new SubOpponent(im, 25, 25);
            mEnemy.setPosition((int) sx, 200);
            mEnemy.defineReferencePixel(13, 13);
            mEnemy.go = "left";
            mLayerManager.append(mEnemy);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void run() {
        while (true) {
            try {
                Graphics g = getGraphics();
                int ox = mHero.getX();
                int oy = mHero.getY();

                if (mHero.isHeroAlive) {
                    mHero.setPosition(ox, oy);
                    int key = getKeyStates();
                    if ((key & LEFT_PRESSED) != 0) {
                        mHero.setFrame(0 + mHero.framefomove++);
                        mHero.setTransform(Sprite.TRANS_NONE);
                        mHero.setPosition(mHero.getX() - 1, mHero.getY());
                        if (mHero.framefomove == 12) {
                            mHero.framefomove = 9;
                        }
                    } else if ((key & RIGHT_PRESSED) != 0) {
                        mHero.setFrame(0 + mHero.framefomove++);
                        mHero.setPosition(mHero.getX() + 1, mHero.getY());
                        mHero.setTransform(Sprite.TRANS_MIRROR);
                        if (mHero.framefomove == 12) {
                            mHero.framefomove = 9;
                        }
                    }
                    if ((key & UP_PRESSED) != 0 && mHero.jump == 0) {
                        mHero.jump = 120;
                        x1 = 10;
                        mHero.framefomove = 9;
                    }
                    if (mHero.jump > 0) {
                        if (mHero.jump > 30) {
                            mHero.setPosition(mHero.getX(), mHero.getY() - (int) x1);
                            mHero.jump--;
                            x1 = x1 * 0.9f;
                        }
                    }

                    if (mHero.getX() < 0) {
                        mHero.setPosition(0, mHero.getY());
                    }

                    if ((mHero.getX() > 170)) {
                        mHero.setPosition(ox, oy);
                        System.out.println(mGround.getX());
                        if ((mGround.getX() > -1100) && (mGround.getX() > -1100)) {
                            //mHero.setPosition(mHero.getX() + 1, mHero.getY());
                            mGround.move(-3, 0);
                            mStone.move(-3, 0);
                            mFire.move(-3, 0);
                        } else {
                            mHero.isTranmitted = false;
                        }
                        //mEnemy.move(-3, 0);

                    }


                    if (mHero.collidesWith(mStone, true)) {
                        mHero.jump = 0;
                        mHero.setPosition(ox, oy);
                        System.out.println("collide");
                    } else {
                        mHero.setPosition(mHero.getX(), mHero.getY() + (int) x2);
                        x2 = x2 * 1.03f;
                        while (mHero.collidesWith(mStone, true)) {
                            mHero.setPosition(mHero.getX(), mHero.getY() - 1);
                            mHero.jump = 0;

                            x2 = 1.0f;
                        }

                    }
                    if (mHero.collidesWith(mFire, true)) {
                        mHero.isHeroAlive = false;
                    }
                } else {
                    audio.stop();
                    midlet.createGameOver();
                    break;
                }
                if (isEnemyAlive == true) {
                    if ("left".equals(mEnemy.go)) {
                        mEnemy.move(-1, 0);
                    } else {
                        mEnemy.move(-1, 0);
                    }
                    if (mEnemy.getX() > 165) {
                        mEnemy.go = "left";
                    }
                    if (mEnemy.getX() < 20) {
                        mEnemy.go = "right";
                    }
                } else {

                    if ("left".equals(mEnemy.go)) {
                        mEnemy.move(-1, 0);
                    } else {
                        mEnemy.move(-1, 0);
                    }
                }

                if (mHero.collidesWith(mEnemy, true) && isEnemyAlive == true) {
                    if (mHero.getY() < mEnemy.getY() - 10) {
                        mEnemy.setFrame(2);
                        isEnemyAlive = false;
                        mLayerManager.remove(mEnemy);
                    } else {
                        mHero.isHeroAlive = false;
                    }
                }

                if (mHero.isTranmitted == false) {
                    audio.stop();
                    midlet.createTranmitted();
                    break;
                }



                mLayerManager.paint(g, 0, 0);
                g.setColor(255, 255, 255);
                g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE));
                g.drawString(String.valueOf(score), 20, 30, g.TOP|g.LEFT);
                score --;
                flushGraphics();
                Thread.sleep(7);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    public void commandAction(Command c, Displayable d) {
    }
}